/**
 * TodoList
 */

import {
  CSSProperties,
  useMemo,
  useEffect,
  useCallback,
  useContext,
  useState,
} from "react";
import TodoItem, { DataItem } from "./_components/TodoItem";
import { Button, Input, Modal } from "antd";
import { debounce, isDev } from "@/utils";
import LeftSide from "./_components/LeftSide";
import RightSide from "./_components/RightSide";
import { useStoreSlice } from "@/hooks";
import { PopupContext } from "@/components/provider/PopupProvider";
import AddToItem, { AddArgs } from "./AddToItem";
import { showMessage } from "@/components/_utils";
import VerticalList from "@/components/VerticalList";
import s from "./index.module.less";

interface Props {
  className?: string;
  style?: CSSProperties;
  [key: string]: any;
}

let index = 0;

const strongStyle = { color: "red", margin: "0 4px" };

function getDataItem(id: number): DataItem {
  return {
    id,
    checked: false,
    value: "测试项" + id,
  };
}
const allList = Array(10000)
  .fill("")
  .map((it: string, ind: number) => {
    index++;
    return getDataItem(ind);
  });

function GetListAsync(
  currPage: number = 1,
  pageSize: number = 100
): Promise<DataItem[]> {
  const startInd = (currPage - 1) * pageSize;
  const endInd = currPage * pageSize;
  return new Promise((resolve, reject) => {
    resolve(allList.slice(startInd, endInd));
  });
}

let endIndex = 0;
export default ({ className = "", children, ...restProps }: Props) => {
  const { openPopup, closePopup } = useContext(PopupContext);
  const [searchVal, setSearchVal] = useState("");
  const { list, updateBaseState } = useStoreSlice("base");
  const [currList, setCurrList] = useState<DataItem[]>([]);
  // 因为考虑到过滤的数据量有点大，所以考虑用useMemo包裹处理
  const filterList = useMemo<DataItem[] | null>(() => {
    if (!searchVal) return null;
    return list.filter((it: DataItem) => it.value.includes(searchVal));
  }, [list, searchVal]);
  // 因为考虑到过滤的数据量有点大，所以考虑用useMemo包裹处理
  const seledKeys = useMemo(() => {
    const mergeList = filterList ?? list;
    setCurrList(mergeList.slice(0, endIndex));
    return mergeList.filter((it: DataItem) => it.checked);
  }, [list, filterList]);
  useEffect(() => {
    !list.length && initList();
  }, []);
  // 模拟请求
  function initList() {
    GetListAsync(1, 10000).then((res: DataItem[]) => {
      console.log("模拟axios请求拿到了数据：", res);
      updateBaseState({ list: res });
      setCurrList(res.slice(0, endIndex));
    });
  }
  // 切换全选/取消全选状态
  function toggleAllSelect() {
    const mergeList = filterList ?? list;
    const isAllSeled = seledKeys.length === mergeList.length;
    const newList = list.map((item: DataItem) => {
      if (filterList) {
        const isAt = !!filterList.find((it: DataItem) => it.id === item.id);
        return { ...item, checked: isAt ? !isAllSeled : item.checked };
      } else {
        return { ...item, checked: !isAllSeled };
      }
    });
    updateBaseState({ list: newList });
  }
  function handleBlur(val: string, id: number) {
    const ind = list.findIndex((it: DataItem) => it.id === id);
    if (ind === -1) return;
    const newList = structuredClone(list);
    newList[ind].value = val;
    updateBaseState({ list: newList });
  }
  // 新增
  function handleAdd(data: AddArgs) {
    const newList = structuredClone(list);
    newList.push({ ...data, checked: false });
    updateBaseState({ list: newList });
    showMessage("新增成功");
    closePopup();
  }
  // 删除
  function handleDelete(id: number) {
    const ind = list.findIndex((it: DataItem) => it.id === id);
    if (ind === -1) return;
    const newList = structuredClone(list);
    newList.splice(ind, 1);
    updateBaseState({ list: newList });
    showMessage("已删除");
  }
  // 批量删除
  function handleBatchDelete() {
    const newList = list.filter((it: DataItem) => !it.checked);
    updateBaseState({ list: newList });
    showMessage("已批量删除");
  }
  function openDeleteConfirm() {
    Modal.confirm({
      title: "温馨提示",
      content: (
        <div className="f-fs-b-w">
          确定<strong style={strongStyle}>删除</strong>共
          <strong style={strongStyle}>{seledKeys.length}</strong> 条数据？
        </div>
      ),
      onOk: handleBatchDelete,
    });
  }
  function handleChange(isChecked: boolean, id: number) {
    const ind = list.findIndex((it: DataItem) => it.id === id);
    if (ind === -1) return;
    const newList = structuredClone(list);
    newList[ind].checked = isChecked;
    updateBaseState({ list: newList });
  }
  const debounceHandleFilter = useCallback(
    debounce((e) => setSearchVal(e.target?.value), false, 500),
    []
  );
  function handleLoadMore(sInd: number, eInd: number) {
    endIndex = eInd;
    setCurrList((filterList ?? list).slice(sInd, eInd));
  }
  return (
    <div className={`${className} ${s["todo-list"]} f-sb-s`}>
      <LeftSide className={`${s.left} ${s["side-box"]} f-1`} />
      <div className={`${s.middle} f-fs-s-c`} {...restProps}>
        <header className={`${s.header} f-sb-c f-0`}>
          <div className="f-1 f-fs-c">
            <Button
              onClick={() =>
                openPopup(
                  "新增TodoItem",
                  <AddToItem id={++index} onConfirm={handleAdd} />
                  // "drawer" //第三个参数可以打开抽屉(drawer)，默认是弹窗(modal)
                )
              }
              className={`${s.btn}`}
              type="primary"
            >
              新增
            </Button>
            {list.length > 0 && (
              <>
                <Button
                  className={`${s.btn}`}
                  type="primary"
                  danger
                  onClick={openDeleteConfirm}
                  disabled={!seledKeys.length}
                >
                  删除
                </Button>
                <Button
                  onClick={toggleAllSelect}
                  className={`${s.btn}`}
                  type="primary"
                  ghost
                >
                  {seledKeys.length < list.length ? "全选" : "全不选"}
                </Button>
              </>
            )}
          </div>
          <Input
            className={`${s.inp} f-0 ml-32`}
            placeholder="请输入关键词进行搜索"
            onInput={debounceHandleFilter}
            onChange={debounceHandleFilter}
            allowClear
          />
        </header>
        <VerticalList className={`${s.bodyer} f-1`} onLoadMore={handleLoadMore}>
          {currList.map((item: DataItem, ind: number) => {
            return (
              <TodoItem
                className={`${s.item}`}
                data={item}
                onBlur={(val: string) => handleBlur(val, item.id)}
                onDelete={() => handleDelete(item.id)}
                onChange={(checkedVal: boolean) =>
                  handleChange(checkedVal, item.id)
                }
                key={item.id}
              >
                {item.value}
              </TodoItem>
            );
          })}
        </VerticalList>
        <footer className={`${s.footer} ${isDev ? "f-sb-c" : "f-fe-c"} f-0`}>
          {isDev && (
            <Button
              onClick={() => {
                localStorage.removeItem("base");
                initList();
                setSearchVal("");
              }}
              danger
            >
              重置
            </Button>
          )}
          <div>
            共 <b>{(filterList ?? list).length}</b> 条
          </div>
        </footer>
      </div>
      <RightSide className={`${s.right} ${s["side-box"]} f-1`} />
    </div>
  );
};
